package shopping.demo.service;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import shopping.demo.cache.UserCache;
import shopping.demo.dao.UserDao;
import shopping.demo.entities.User;
import shopping.demo.exception.user.UserMoneyNotEnoughException;
import shopping.demo.exception.user.UserAlreadyExistException;
import shopping.demo.exception.user.UserNotExistException;
import shopping.demo.exception.user.UserNotValidException;

import java.util.List;

@Service
public class UserService {
    @Autowired
    private UserDao userDao;
    @Autowired
    private UserCache userCache;
    private final Object lock = new Object();
    private Logger logger = LoggerFactory.getLogger(Logger.class);

    //所有用户的预热进redis
//    @PostConstruct
//    public void init() {
//        for(User user : userDao.findAll()) {
//            userCache.setUserCache(user);
//        }
//        logger.info("User预热完毕");
//    }

    public List<User> findAll() {
        List<User> users = userCache.getUsers();
        return users.size() == 0? userDao.findAll():users;
    }

    public User findByUserId(Long userId) {
        User user = userCache.getUserCache(userId);
        if(user == null) {
            //缓存未命中
            synchronized (this.lock) {
                user = userCache.getUserCache(userId);
                //double check lock
                if(user == null) {
                    User new_user = userDao.findByUserId(userId);
                    //说明数据库中也找不到用户信息
                    if(new_user == null) {
                        throw new UserNotExistException();
                    }
                    userCache.setUserCache(new_user);
                    return new_user;
                }else {
                    return user;
                }
            }
        }
        return user;
    }

    @Transactional
    public void deleteByUserId(Long userId) throws Exception{
        userCache.deleteUserCache(userId);
        if(userDao.findByUserId(userId) == null) {
            throw new UserNotExistException();
        }

        userDao.deleteByUserId(userId);
    }

    @Transactional
    public void changePassword(Long userId, String password) throws Exception {
        //先删除缓存
        userCache.deleteUserCache(userId);
        //更新数据库
        if(userDao.findByUserId(userId) == null) {
            throw new UserNotExistException();
        }
        userDao.changePassword(userId, password);
        logger.info("修改密码成功");
    }

    @Transactional
    public void moneyDown(Long userId, Integer cost) throws Exception {
        //删除缓存
        userCache.deleteUserCache(userId);
        //更新数据库
        User user = userDao.findByUserId(userId);
        //判断user是否存在
        if(user == null) {
            throw new UserNotExistException();
        }
        int money = user.getMoney();
        //判断资金是否充足
        if(money < cost) {
            throw new UserMoneyNotEnoughException();
        }
        userDao.moneyDown(userId, cost);
        logger.info("用户"+userId+"花费了"+cost);
    }

    @Transactional
    public void moneyUp(Long userId) throws Exception{
        //删除缓存
        userCache.deleteUserCache(userId);
        //判断用户是否存在
        if(userDao.findByUserId(userId) == null) {
            throw new UserNotExistException();
        }
        userDao.moneyUp(userId);
        logger.info("用户"+userId+"充值了100元");
    }

    @Transactional
    public void insertUser(User user) throws Exception{
        //检验用户是否存在
        if(userDao.findByUserId(user.getUserId()) != null) {
            throw new UserAlreadyExistException();
        }
        int count = userDao.insertUser(user.getUserId(),user.getUsername(), user.getPassword(), user.getMoney());
        if(count == 0) {
            throw new UserNotValidException();
        }
        logger.info("创建了新用户"+user.getUsername());
    }
}
